Skip to content

Fix: Infinite recursion crash in wikitext parser#308

Merged
nsh07 merged 4 commits intonsh07:mainfrom
sayeedjoy:main
Jan 11, 2026
Merged

Fix: Infinite recursion crash in wikitext parser#308
nsh07 merged 4 commits intonsh07:mainfrom
sayeedjoy:main

Conversation

@sayeedjoy
Copy link
Copy Markdown
Contributor

Problem

The app kept crashing with a StackOverflowError on some Wikipedia pages because the toWikitextAnnotatedString function was getting stuck in an endless loop. Certain templates like {{small}} were sending the same wikitext back into the parser again and again, which caused the function to call itself repeatedly until the app crashed.

Stack Trace Sample

 at org.nsh07.wikireader.parser.WikitextToAnnotatedStringKt.toWikitextAnnotatedString(wikitextToAnnotatedString.kt:592)
  at org.nsh07.wikireader.parser.WikitextToAnnotatedStringKt$$ExternalSyntheticLambda1.invoke(D8$$SyntheticClass:0)
  at org.nsh07.wikireader.parser.WikitextToAnnotatedStringKt.toWikitextAnnotatedString(wikitextToAnnotatedString.kt:592)
  at org.nsh07.wikireader.parser.WikitextToAnnotatedStringKt$$ExternalSyntheticLambda1.invoke(D8$$SyntheticClass:0)

Solution

Implemented a two-part fix:

1. Recursion Depth Guard

  • Added a thread-local recursion counter with a maximum depth of 64 nested parsing calls
  • When the limit is reached, the parser returns plain text (AnnotatedString(this)) instead of crashing
  • The guard uses a try/finally block to ensure proper cleanup of the recursion counter

2. Template Branch Hardening

  • Fixed multiple template handlers that could cause infinite recursion when used without parameters
  • Changed substringAfter('|') to substringAfter('|', "") for templates like:
    • {{abbr}}, {{efn}}, {{val}}, {{var}}, {{small}} family, {{dfn}}, {{US$}}, {{hatnote}}, {{rp}}, {{isbn}}, {{sfrac}}, {{unichar}}, {{char}}, {{noflag}}, {{nowrap}} family, {{url}}, {{format price}}, {{transliteration}}
  • This ensures that when a template has no | parameter, the parser receives an empty string instead of the full template text, preventing self-recursion

Changes

  • File: app/src/main/java/org/nsh07/wikireader/parser/wikitextToAnnotatedString.kt
    • Added MAX_WIKITEXT_RECURSION_DEPTH constant (64)
    • Added WikitextParserState object with thread-local recursion counter
    • Added recursion guard at the start of toWikitextAnnotatedString function
    • Hardened 20+ template branches to prevent infinite recursion

Testing

  • Verified no compilation errors
  • Test on previously crashing Wikipedia pages
  • Verify normal content (links, headings, references, templates) still renders correctly
  • Confirm app no longer crashes with StackOverflowError

Notes

  • In extreme edge cases with deeply nested or malformed templates, the parser may display raw wikitext instead of fully parsed content. This is intentional to prevent crashes.
  • The recursion limit of 64 should be sufficient for all legitimate Wikipedia content while preventing runaway recursion.

Copilot AI review requested due to automatic review settings December 5, 2025 17:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a critical infinite recursion bug in the wikitext parser that was causing StackOverflowError crashes when parsing certain Wikipedia templates. The solution implements a two-pronged approach: a recursion depth guard and hardening of template parameter extraction.

Key changes:

  • Added a ThreadLocal recursion depth counter with a maximum depth of 64 to gracefully handle deeply nested or malformed wikitext
  • Fixed 18+ template handlers to use substringAfter('|', "") with an empty string default, preventing self-recursion when templates lack parameters

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/src/main/java/org/nsh07/wikireader/parser/wikitextToAnnotatedString.kt Outdated
Comment thread app/src/main/java/org/nsh07/wikireader/parser/wikitextToAnnotatedString.kt Outdated
@nsh07
Copy link
Copy Markdown
Owner

nsh07 commented Dec 7, 2025

Looks good to me. Can you please fix the changes Copilot has suggested? Otherwise it's good.

sayeedjoy and others added 2 commits December 7, 2025 13:41
…tedString.kt

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…tedString.kt

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@sayeedjoy
Copy link
Copy Markdown
Contributor Author

Looks good to me. Can you please fix the changes Copilot has suggested? Otherwise it's good.

Copilot suggestions accepted.

@sayeedjoy
Copy link
Copy Markdown
Contributor Author

Hi @nsh07 ,
I’ve applied the fix for #307 Could you please check it? Thanks!

@nsh07
Copy link
Copy Markdown
Owner

nsh07 commented Jan 9, 2026

Hey, I'm really sorry for not merging this PR for so long, I've been having a lack of time recently and I was working on another app, and i couldn't work on this at all. I'll merge this tomorrow. Thanks for your patience!

@nsh07 nsh07 merged commit fc5c017 into nsh07:main Jan 11, 2026
1 check passed
@nsh07
Copy link
Copy Markdown
Owner

nsh07 commented Jan 11, 2026

Thanks for contributing!

@sayeedjoy
Copy link
Copy Markdown
Contributor Author

Pleasure! I’ll try to contribute more going forward 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants